package com.cskaoyan.javase.oop3._2inner._1member._1use;

import javax.xml.transform.Source;

/**
 * 首先内部类和外围类是"好兄弟"的关系,互相之间的访问是不受权限限制的
 *
 * 在具体了解成员内部类的使用之前,我们要搞清楚成员内部类和外围类之间,到底什么关系?
 *      成员内部类可以看成外围类的一个成员
 * 具体来说:
 *      类中的成员变量,必须依赖于类的对象而存在
 *      那么:
 *      成员内部类的对象,也必须依赖于外围类对象而存在
 *      也就是说,要想得到成员内部类对象,必须在外围类对象的基础上创建,成员内部类对象不能单独创建.
 *      成员内部类依赖于外围类,反过来,没有依赖关系
 *      之所以存在这样的依赖关系:
 *          是因为成员内部类对象的成员变量列表中,都会持有外围类对象的引用
 *
 * 成员内部类和外围类之间具有依赖关系,具体在访问和使用时的体现是:
 *      成员内部类内部访问外围类(重点)
 *          访问的位置一般都是方法中,成员内部类只有成员方法,还有构造器
 *          那么问题来了,在成员内部类的成员方法中,如何访问外围类成员呢?
 *          要想访问外围类成员,首先需要外围类对象
 *          那么这里需要创建外围类对象吗?
 *          在成员内部类的成员方法中,存在几个对象呢?
 *              首先肯定存在this指向当前成员内部类对象
 *              其次还存在外围类对象,用"外围类类名.this"指向外围类对象
 *
 *
 *
 * 成员内部类的访问特点,主要从以下几个角度研究：
 *      1.成员内部类内部访问外围类(重点)
 *          既然已经存在外围类对象了
 *          那么直接访问外围类成员即可,因为外围类对象和this指向当前对象一样,都是一个隐式传参.
 *          当成员内部类和外围类之间存在同名成员时
 *          用"外围类类名.this"指向外围类对象来作区分
 *
 *      2.外围类访问成员内部类成员(重点)
 *          首先仍然是考虑访问的位置
 *          外围类中的访问要分两种情况:
 *              a.成员方法
 *                  访问成员内部类成员,首先需要成员内部类对象
 *                  外围类的成员方法中存在几个对象?
 *                  只有一个对象,this指向外围类自身对象
 *                  在这种情况下,如何创建成员内部类对象呢?
 *                  既然外围类对象已经存在了,那么直接创建成员内部类对象即可(直接new).
 *                  创建成员内部类对象以后,用引用(对象名)访问成员内部类成员即可.
 *
 *              b.静态方法
 *              没有任何对象
 *              那么如何创建成员内部类对象呢?
 *              先创建外围类对象,然后在外围类对象的基础上,再创建成员内部类对象
 *              访问的时候,用谁的引用访问,得到的就是谁的成员.
 *
 *      3.外部类访问成员内部类成员(了解)
 *              整个访问的全程都受权限限制
 *              其次,在外部类的访问,什么方法都无所谓
 *              反正都没有外围类对象
 *              都需要先创建外围类对象,然后才能创建成员内部类对象
 *
 *      4.成员内部类访问外部类成员(了解)
 *              随便访问,但是受权限限制
 *              需要new对象然后才能访问.
 *
 * 成员内部类的使用,主要还是为了更好的体系设计,实际开发中,我们不太需要把体系设计的非常完美
 * 所以用得可能不是很多
 *
 * @since 10:16
 * @author wuguidong@cskaoyan.onaliyun.com
 */
// 外部类
public class Demo {
    public static void main(String[] args) {
        EnclosedClazz ec = new EnclosedClazz();
        EnclosedClazz.Inner in = ec.new Inner();

        // 上述语法二合一
        EnclosedClazz.Inner in2 = new EnclosedClazz().new Inner();

        System.out.println(in.a);
        // System.out.println(in.b);
    }
}

// 外围类
class EnclosedClazz {
    int a;
    private int b = 10;
    static int c = 20;
    static final int D = 30;

    // 外围类的成员方法
    public void test() {
        Inner in = new Inner();
        System.out.println(in.a);
        System.out.println(in.b);
        System.out.println(a);
        System.out.println(b);

        // 什么叫做在外围类对象的基础上创建成员内部类对象?
        // 存在this.
        Inner in2 = this.new Inner();
    }

    // 外围类的静态成员方法
    public static void testStatic() {
        EnclosedClazz ec = new EnclosedClazz();
        Inner in = ec.new Inner();

        // 上述语法二合一,链式调用
        Inner in2 = new EnclosedClazz().new Inner();
    }

    // 成员内部类
    class Inner {
        int a;
        private int b = 100;
        // static int c = 20;
        static final int D = 300;

        public void testInner2(int a) {
            System.out.println(a);
            System.out.println(this.a);
            System.out.println(EnclosedClazz.this.a);
        }

        // 成员内部类的成员方法
        public void testInner() {
            System.out.println(a);
            System.out.println(b);
            System.out.println(EnclosedClazz.c);
            System.out.println(EnclosedClazz.D);
            System.out.println(Inner.D);
        }

    }

}